;*********************************************************************
; vec2.asm
; Ejercicio que ingreso por teclado para llenar un vector y luego
; lo recorre y lo imprime por pantalla
;
;*********************************************************************

.model small
.stack
.data

;VARIABLES DEL SORT
TAMMAX  	equ 60	; 30 (elemtos) x 2 (long del elem )
;CANTREG  	equ 30	; 30 (elemtos) x 2 (long del elem )
vector		dw  30 dup(?) ;6,2,5,4,3,9,1,11,0,3
CANTREG  	dw 30	; 30 (elemtos) x 2 (long del elem )
regvec		dw	?
longvec 	dW  ? ;cantidad real de elementos del vector (x 2)
buffer  	dw  ?
;VARIABLES DE SALIDA POR PANTALLA
Actual		dw  ?
ESPACIO		db "  $"
SIG_MENOS	db "- $"
diez		dw	10
dos			dw	2
cadena		db  6 dup(' '),10,13,'$'
signo 		dw ?	; 0 positivo 1 negativo	
;VARIABLES DE MENU PRINCIPAL
msgIng1 	db  "BubbleSort",10,13,"$"
msgIng2 	db  'Ingrese Opcion de Ordenamiento: $' ;,10,13,'$'
msgIng3 	db  '		0 - ascendente',10,13,'$'
msgIng4 	db  '		1 - descendente',10,13,'$'
msgIng5 	db  '		9 - SALIR',10,13,'$'
msgIng6 	db  10,13,'procesando...',10,13,'$'
msgErr1 	db  10,13,'Error al ingresar opcion',10,13,'$'
orden		db	? ; 0 - ascendente 1 -descendente

;VARIABLES DEL ARCHIVO
fileName	db	"sortfreg.dat",0	;el nombre del archivo debe terminar con un 0 binario!!!!
fHandle		dw	?
registro	db	15 dup(?)

msjErrOpen	db	"Error en apertura$"
msjErrRead	db	"Error en lectura$"
msjErrClose	db	"Error en cierre$"

.code
start:

		mov	ax,@data 	;ds <-- dir del segmento de datos
		mov	ds,ax


@@msgxpnt:
		lea	 dx,msgIng1
		call printMsg	
		lea	 dx,msgIng3
		call printMsg
		mov	 dx, offset msgIng4
		call printMsg
		mov	 dx, offset msgIng5
		call printMsg		
		mov	 dx, offset msgIng2
		call printMsg			

		;lee teclado
		mov ah,01h
		int 21h
     
		;ajustando el teclado
		xor ah,ah
		sub al,30h
;		mov cx,2
		;verificando opcion

		cmp  al,9		; solucion a que esta 
		jne  @@continua ; a mas de 128 bytes
		jmp  @@finstart	; if [AL] = 9 -> SALIR 		
@@continua:
;		mov al,0		; solo de prueba
		cmp al,0		;  IF [AL] = 0 ->
		je  @@orden0  	;  	ASCENDENTE 
		cmp al,1		;  IF [AL] = 1 -> 
		je  @@orden1  	; 	DESCENDENTE
		lea	dx,msgErr1
		call printMsg
		jmp	 @@msgxpnt

@@orden0:
		mov orden,al
		jmp @@bblsort

@@orden1: 
		mov orden,al
		jmp @@bblsort
		
@@bblsort: 
		
		call @@abrirArch	;llamo a la subrutina para abrir el archivo
;		call @@imprVector 
		
 		lea	 dx,msgIng6 ;msgIng6 = procesando...
		call printMsg	

		mov	si,0		; i = puntero al vector	
		
		mov ax,longvec	; AX = LONGITUD REAL DEL VECTOR
		cmp ax,TAMMAX   ; IF AX < TAMMAX
		jb  @@lngvec    ; 	a lonvec
		mov	ax,TAMMAX	; ELSE CX = TAMMAX
		
;		jmp @@if1
@@lngvec:
		mov dx,0
		div dos				;	DX:AX div 2 deja DX = resto y AX =cociente		

		mov cx,ax			; CX = AX
;		dec cx				; i < vec[i].length
@@if1:	
		mov	di,0			; j = 0 puntero al vector	
;			push cx			; guardo el valor de cx en la pila
;			mov  cx,ax  	;
@@if2:		
		mov	dx,vector[si]	; dx <- vec[i]
		mov al,[orden]		; 	AL = orden del sort
		cmp al,1			;	IF ORDEN  = 1
		je	@@ord_asc		;     @@orden_asc

		cmp dx,vector[di]   ; IF vec[i] > vec[j]			
		jl  @@swap			; 	SINO intercambio - 1- descendente
		jmp @@salto         ; 	Y	 salto a incrementar j
@@ord_asc:  
		cmp dx,vector[di]   ; IF vec[i] < vec[j]
		jg  @@swap			; 	SINO intercambio - 0- descendente
		jmp @@salto         ; 	Y    salto a incrementar j
@@swap:	
		xor ax,ax
		mov ax,vector[di] 	;AX 	<- vec[j]
		mov [buffer],ax		;buffer <- AX
		mov	ax,vector[si]	;AX 	<- vec[i]
		mov vector[di],ax 	;vec[j] <- vec[i]
		mov ax,[buffer]
		mov vector[si],ax   ;vec[i]=buffer
			
@@salto: 	
		add	di,2			; j++ 2 bytes a la prox palabra}   
		cmp di,si			; si=i di =j
		jb @@if2			; si j > i vuelve al if	
;		pop cx				; recupero el valor de cx		
		
		add	si,2		; me adelanto al prox elemento
;		sub	cx,2		
;		cmp cx,0		;IF CX >= 0
;		jae	@@if1		;  @@if1
		
		loop @@if1		; resta 1 a cx y si es <> 0 bifurca a 'otro
		
		call @@imprVector 
	
@@finstart:		
			mov	ax,4c00h	; retornar al DOS
			int	21h

;******* RUTINAS INTERNAS **************************************
;******* IMPRIMIR MENSAJE POR PANTALLA**************************
printMsg:
		mov	ah,9  ; servicio 9 para int 21 -- Imprimir cadena en pantalla
		int	21h
		ret
;******* LIMPIA REGISTRO A IMPRIMIR POR PANTALLA ***************		
@@limpiaReg:	
		mov cx,5
		mov si,0
@@blanco:  
		mov cadena[si],' '
		inc si
		loop @@blanco  
		ret
;******* ABRIR ARCHIVOS*****************************************				
@@abrirArch:
		;ABRE EL ARCHIVO PARA LECTURA
		mov	al,0		         ;al = tipo de acceso (0=lectura; 1=escritura; 2=lectura y escritura)
		mov	dx,offset fileName	 ;dx = dir del nombre del archivo
		mov	ah,3dh		         ;ah = servicio para abrir archivo 3dh
		int	21h
		jc	errOpen				 ;jc = salta si acarreo
		mov	fHandle,ax	         ; en ax queda el handle del archivo

		mov	si,0
		mov longvec,0
@@otroElem:
		;LEE EL ARCHIVO (registro 1)
		mov	bx,fHandle	;bx = handle del archivo
		mov cx,2		;cx = cantidad de bytes a copiar

		mov dx,offset regvec ;dx = dir del area de memoria q contiene los bytes leidos del archivo
		mov	ah,3fh			;ah = servicio para leer un archivo: 3fh
		int	21h
		jc	errRead
		cmp ax,0
		je 	@@cierraArch 	; fin de archivo

		mov si,longvec		; si <-longvect
		cmp si,TAMMAX   	; IF SI >= TAMMAX(60) - max espacio guardado
		jae @@cierraArch 	;  	no toma mas registros y cierra el archivo 		
		
		mov dx,regvec		; dx = regvec
		mov	vector[si],dx	; guardo el elemento en el vector
		add	si,2			; me adelanto 2 en el vector (por ser 2 bytes)
		mov dx,si			; DX = SI 
		mov longvec,dx		; longvec = dx - cant de elemntos dle vector
		jmp	@@otroElem

@@cierraArch:		
		;CIERRA EL ARCHIVO
		mov	bx,fHandle	;bx = handle del archivo
		mov	ah,3eh		;ah = servicio para cerrar archivo: 3eh
		int	21h
		jc	errClose
		jmp	@@finabriArch

errOpen:
		mov	dx,offset msjErrOpen
		mov	ah,9
		int	21h
		jmp	@@finstart
errRead:
		mov	dx,offset msjErrRead
		mov	ah,9
		int	21h
		jmp	@@finstart
errClose:
		mov	dx,offset msjErrClose
		mov	ah,9
		int	21h
		jmp	@@finstart

@@finabriArch:
		ret
;***************************************************************	

;******* IMPRIMIR VECTOR ***************************************
@@imprVector: 
		mov si,0
@@verFinLista:
		mov actual,si		; actual = guarda SI  (el corriente)
		cmp si,longvec		; IF SI = longvec
		jnb @@finImprVector	;  	salto a finImprVector

		mov dx,0
		mov ax,vector[si]	; AX = VEC [i]
		cmp ax,0			; IF AX >= 0
		jge @@es_posit		; 	ES POSITIVO

;		lea  dx,SIG_MENOS	; ELSE 
;		call printMsg		; 	imprime signo negativo
		mov signo,1
		mov si,actual		;	SI = recupero el corriente
		mov ax,vector[si]	;   AX = VEC[i]
		mov dx,0   			;	complementa y suma 1	
;		not ax				;
;		add ax,1			;	AX = not AX + 1
							;	NEG HACE LO MISMO
		neg ax				; 	AX = not(AX) +1

@@es_posit:
		call @@limpiaReg	; 
		mov  si,5			;	si apunta al ultimo byte de la cadena
@@otraDiv:
		div  diez			;	DX:AX div 10 deja DX = resto y AX =cociente

		add  dx,48			;	convierte a Ascii el resto
		mov  cadena[si],dl	;	lo pongo en la posicion anterior
		sub  si,1			;	posiciono SI en el caracter anterior en la cadena
	
		cmp  ax,diez		;	IF cociente < 10
		jl   finDiv			;		imprimo el numero
							;       fin division
							;	SINO	
		mov  dx,0			;	  DX = 0 para DX:AX
		jmp  @@otraDiv	    ;     Y VUELVE A DIVIDIR
finDiv:
		add  ax,48
		mov  cadena[si],al

		cmp  signo,1		; IF SIGNO = 1 --NEGATIVO
		je	 @@es_neg		; 	PONGO EL SIGNO
		lea  dx,ESPACIO		; si es posito solo pongo espacio
		jmp	 @@salto01
@@es_neg:		
		lea  dx,SIG_MENOS	; ELSE 
@@salto01:
		call printMsg		; 	imprime signo negativo o espacio	
		mov  signo,0		;   limpio el signo	
		
		lea  dx,cadena		;   imprime el numero
		call printMsg

;		lea dx,espacio
;		call printMsg
;		lea dx,CRLF			; SALTO DE LINEA Y RETORNO
;		call printMsg
		
        mov si,actual		; SI = recupera el corriente
		add si,2			; SI INCREMENTADO EN 2 (POR 2 BYTES)

        jmp  @@verfinLista
  
@@finImprVector:
        ret
;---------------------------------------------------------------------;		
end start